﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Models;
using WalkingTec.Mvvm.Core;
using HengTong.Model.Extension;
using System.Linq;
using System.Net.Http;
using System.Numerics;
using AlibabaCloud.OpenApiClient.Models;
using AlibabaCloud.TeaUtil.Models;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using WalkingTec.Mvvm.Core.Support.FileHandlers;

namespace HengTong.Model.Services
{
    /// <summary>
    /// 人像检测和证件照生成服务接口
    /// </summary>
    public interface IPortraitPhotoService
    {
        /// <summary>
        /// 检测人像照片是否符合证件照规则
        /// </summary>
        /// <param name="imageId">图片ID</param>
        /// <returns>检测结果，成功返回"检测通过"，失败返回错误信息</returns>
        Task<Result<string>> ValidatePortraitAsync(Guid imageId);

        /// <summary>
        /// 生成证件照
        /// 使用人体分割+人脸关键点检测的方式生成高质量证件照
        /// </summary>
        /// <param name="imageId">原图片ID</param>
        /// <param name="backgroundColor">背景颜色</param>
        /// <param name="size">证件照尺寸</param>
        /// <returns>生成的证件照字节数组</returns>
        Task<Result<Guid>> GenerateIdPhotoAsync(Guid imageId,
            PortraitPhotoService.IdPhotoBackgroundColor backgroundColor,
            PortraitPhotoService.IdPhotoSize size);
    }

    /// <summary>
    /// 人像检测和证件照生成服务实现
    /// 基于阿里云视觉智能开放平台Facebody API
    /// </summary>
    public class PortraitPhotoService : IPortraitPhotoService
    {
        private readonly WTMContext _context;
        private readonly ILogger<PortraitPhotoService> _logger;

        public PortraitPhotoService(WTMContext context, ILogger<PortraitPhotoService> logger)
        {
            _context = context;
            _logger = logger;
        }


        /// <summary>
        /// 检测人像照片是否符合证件照规则
        /// 检测项目：人脸数量、角度、模糊度、像素等
        /// 如果检测不通过，自动删除图片文件
        /// </summary>
        /// <param name="imageId">图片ID</param>
        /// <returns>检测结果，成功返回"检测通过"，失败返回错误信息</returns>
        public async Task<Result<string>> ValidatePortraitAsync(Guid imageId)
        {
            bool shouldDeleteFile = false;
            string errorMessage = null;

            try
            {
                _logger.LogInformation($"开始检测人像照片是否符合证件照规则，ImageId: {imageId}");

                // 获取图片数据
                var imageDataResult = await GetImageDataAsync(imageId);
                if (imageDataResult.Code != 200)
                {
                    return new Result<string>(imageDataResult.Message);
                }

                var imageData = imageDataResult.Data;
                _logger.LogInformation($"获取到图片数据，大小: {imageData.Length} bytes");

                // 检查图片大小限制（5MB）
                if (imageData.Length > 5 * 1024 * 1024)
                {
                    _logger.LogWarning($"图片文件过大: {imageData.Length} bytes，超过5MB限制");
                    shouldDeleteFile = true;
                    errorMessage = "图片文件过大";
                    return new Result<string>(errorMessage);
                }

                // 获取阿里云配置
                var siteConfig = _context.GetSiteConfig();
                var accessKeyId = siteConfig.AliyunOcrAppKey;
                var accessKeySecret = siteConfig.AliyunOcrAppSecret;

                if (string.IsNullOrEmpty(accessKeyId) || string.IsNullOrEmpty(accessKeySecret))
                {
                    _logger.LogError("阿里云配置不完整，缺少AccessKeyId或AccessKeySecret");
                    shouldDeleteFile = true;
                    errorMessage = "系统配置错误";
                    return new Result<string>(errorMessage);
                }

                // 创建阿里云客户端 - 使用facebody endpoint
                var config = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    AccessKeyId = accessKeyId,
                    AccessKeySecret = accessKeySecret,
                    Endpoint = "facebody.cn-shanghai.aliyuncs.com"
                };
                var client = new AlibabaCloud.SDK.Facebody20191230.Client(config);

                _logger.LogInformation("开始调用阿里云人脸检测API");

                var detectFaceRequest = new AlibabaCloud.SDK.Facebody20191230.Models.DetectFaceAdvanceRequest
                {
                    ImageURLObject = new MemoryStream(imageData)
                };

                // 创建运行时选项
                var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();

                var response = await client.DetectFaceAdvanceAsync(detectFaceRequest, runtime);

                _logger.LogInformation("人脸检测API调用完成");

                // 检查响应 - Facebody SDK 直接返回数据，不需要检查Code
                var data = response.Body.Data;
                if (data == null)
                {
                    _logger.LogError("人脸检测API返回数据为空");
                    shouldDeleteFile = true;
                    errorMessage = "检测失败";
                    return new Result<string>(errorMessage);
                }

                var faceCount = data.FaceCount ?? 0;

                _logger.LogInformation($"检测到人脸数量: {faceCount}");

                // 检查人脸数量
                if (faceCount == 0)
                {
                    _logger.LogWarning("未检测到人脸，请确保照片中有清晰的人脸");
                    shouldDeleteFile = true;
                    errorMessage = "未检测到人脸，请确保照片中有清晰的人脸";
                    return new Result<string>(errorMessage);
                }

                if (faceCount > 1)
                {
                    _logger.LogWarning($"检测到多个人脸: {faceCount}个");
                    shouldDeleteFile = true;
                    errorMessage = "检测到多个人脸";
                    return new Result<string>(errorMessage);
                }

                // 检查人脸质量 - 使用质量分数数组
                var qualities = data.Qualities;
                if (qualities == null)
                {
                    _logger.LogWarning("无法获取人脸质量信息");
                    shouldDeleteFile = true;
                    errorMessage = "质量检测失败";
                    return new Result<string>(errorMessage);
                }

                // 获取第一个人脸的质量分数
                var blurScore = qualities.BlurList?.FirstOrDefault() ?? 0;
                var poseScore = qualities.PoseList?.FirstOrDefault() ?? 0;
                var illumScore = qualities.IlluList?.FirstOrDefault() ?? 0;
                var maskScore = qualities.MaskList?.FirstOrDefault() ?? 0;

                _logger.LogInformation(
                    $"人脸质量检测结果 - 模糊度分数: {blurScore}, 姿态分数: {poseScore}, 光照分数: {illumScore}, 口罩分数: {maskScore}");

                // 检查人脸质量 - 使用85分阈值
                const float qualityThreshold = 85.0f;

                if (blurScore < qualityThreshold)
                {
                    _logger.LogWarning($"人脸模糊度不合格，分数: {blurScore}");
                    shouldDeleteFile = true;
                    errorMessage = "照片模糊";
                    return new Result<string>(errorMessage);
                }

                if (poseScore < qualityThreshold)
                {
                    _logger.LogWarning($"人脸姿态不合格，分数: {poseScore}");
                    shouldDeleteFile = true;
                    errorMessage = "姿态不正";
                    return new Result<string>(errorMessage);
                }

                if (illumScore < qualityThreshold)
                {
                    _logger.LogWarning($"光照条件不合格，分数: {illumScore}");
                    shouldDeleteFile = true;
                    errorMessage = "光照不佳";
                    return new Result<string>(errorMessage);
                }

                if (maskScore < qualityThreshold)
                {
                    _logger.LogWarning($"检测到面部遮挡，分数: {maskScore}");
                    shouldDeleteFile = true;
                    errorMessage = "面部遮挡";
                    return new Result<string>(errorMessage);
                }

                _logger.LogInformation("人像照片检测通过，符合证件照规则");
                return new Result<string>
                {
                    Code = 200,
                    Message = "检测通过",
                    Data = "检测通过"
                };
            }
            catch (Tea.TeaException ex) when (ex.Code == "404" || ex.Message.Contains("EAS_FACE_NOT_EXIST"))
            {
                // 阿里云API返回的人脸未检测到异常
                _logger.LogWarning($"阿里云API未检测到人脸，请确保照片中有清晰的人脸，ImageId: {imageId}");
                shouldDeleteFile = true;
                errorMessage = "未检测到人脸，请确保照片中有清晰的人脸";
                return new Result<string>(errorMessage);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"人像照片检测异常，ImageId: {imageId}");
                shouldDeleteFile = true;
                errorMessage = "检测异常";
                return new Result<string>(errorMessage);
            }
            finally
            {
                // 统一处理文件删除
                if (shouldDeleteFile)
                {
                    await DeleteImageFileAsync(imageId);
                }
            }
        }

        /// <summary>
        /// 删除图片文件（私有方法）
        /// </summary>
        /// <param name="imageId">图片ID</param>
        private async Task DeleteImageFileAsync(Guid imageId)
        {
            try
            {
                var scope = _context.ServiceProvider.CreateScope();
                var wtmFileProvider = scope.ServiceProvider.GetRequiredService<WtmFileProvider>();
                var dc = scope.ServiceProvider.GetRequiredService<WTMContext>().DC;

                // 使用WtmFileProvider删除文件，这样会同时删除数据库记录和文件
                wtmFileProvider.DeleteFile(imageId.ToString(), dc);
                // 手动保存更改以确保数据库操作生效
                await dc.SaveChangesAsync();

                _logger.LogInformation($"已删除不合格的图片文件，ImageId: {imageId}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"删除图片文件失败，ImageId: {imageId}");
            }
        }


        /// <summary>
        /// 证件照背景颜色枚举
        /// </summary>
        public enum IdPhotoBackgroundColor
        {
            White,
            Red,
            Blue
        }

        /// <summary>
        /// 证件照尺寸枚举
        /// </summary>
        public enum IdPhotoSize
        {
            OneInch, // 一寸 295x413
            TwoInch, // 二寸 413x579
            SmallTwoInch // 小二寸 413x531
        }

        /// <summary>
        /// 生成证件照
        /// 使用人体分割+人脸关键点检测的方式生成高质量证件照
        /// 生成后会删除原图片，保存新的证件照图片
        /// </summary>
        /// <param name="imageId">原图片ID</param>
        /// <param name="backgroundColor">背景颜色</param>
        /// <param name="size">证件照尺寸</param>
        /// <returns>生成的证件照新图片ID</returns>
        /// <summary>
        /// 优化版证件照生成方法 - 基于官方算法实现
        /// </summary>
        public async Task<Result<Guid>> GenerateIdPhotoAsync(Guid imageId,
            IdPhotoBackgroundColor backgroundColor,
            IdPhotoSize size)
        {
            try
            {
                _logger.LogInformation($"开始生成高质量证件照，ImageId: {imageId}, 背景颜色: {backgroundColor}, 尺寸: {size}");

                // 1. 获取图片数据
                var imageDataResult = await GetImageDataAsync(imageId);
                if (imageDataResult.Code != 200)
                {
                    return new Result<Guid>(imageDataResult.Message);
                }

                var imageData = imageDataResult.Data;

                // 2. 获取阿里云配置
                var siteConfig = _context.GetSiteConfig();
                var accessKeyId = siteConfig.AliyunOcrAppKey;
                var accessKeySecret = siteConfig.AliyunOcrAppSecret;

                if (string.IsNullOrEmpty(accessKeyId) || string.IsNullOrEmpty(accessKeySecret))
                {
                    _logger.LogError("阿里云配置不完整");
                    return new Result<Guid>("阿里云配置不完整");
                }

                // 3. 创建阿里云客户端
                var faceConfig = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    AccessKeyId = accessKeyId,
                    AccessKeySecret = accessKeySecret,
                    Endpoint = "facebody.cn-shanghai.aliyuncs.com"
                };

                var segConfig = new AlibabaCloud.OpenApiClient.Models.Config
                {
                    AccessKeyId = accessKeyId,
                    AccessKeySecret = accessKeySecret,
                    Endpoint = "imageseg.cn-shanghai.aliyuncs.com"
                };

                var faceClient = new AlibabaCloud.SDK.Facebody20191230.Client(faceConfig);
                var segClient = new AlibabaCloud.SDK.Imageseg20191230.Client(segConfig);
                var runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();

                // 4. 获取人脸关键点信息 - 使用高精度模式
                _logger.LogInformation("调用人脸检测与关键点定位API");
                var detectFaceRequest = new AlibabaCloud.SDK.Facebody20191230.Models.DetectFaceAdvanceRequest
                {
                    ImageURLObject = new MemoryStream(imageData)
                };
                var faceResponse = await faceClient.DetectFaceAdvanceAsync(detectFaceRequest, runtime);

                if (faceResponse.Body.Data?.Landmarks == null || !faceResponse.Body.Data.Landmarks.Any())
                {
                    _logger.LogError("未获取到人脸关键点信息");
                    return new Result<Guid>("未获取到人脸关键点信息");
                }

                var landmarks = faceResponse.Body.Data.Landmarks;
                _logger.LogInformation($"获取到人脸关键点数量: {landmarks.Count}");

                // 5. 获取人体分割图 - 使用精确的人体分割
                _logger.LogInformation("调用高精度人体分割API");
                var segmentRequest = new AlibabaCloud.SDK.Imageseg20191230.Models.SegmentBodyAdvanceRequest
                {
                    ImageURLObject = new MemoryStream(imageData)
                };
                var segResponse = await segClient.SegmentBodyAdvanceAsync(segmentRequest, runtime);

                if (string.IsNullOrEmpty(segResponse.Body.Data?.ImageURL))
                {
                    _logger.LogError("人体分割失败");
                    return new Result<Guid>("人体分割失败");
                }

                // 下载分割后的图片
                var segmentedImageData = await DownloadImageAsync(segResponse.Body.Data.ImageURL);
                if (segmentedImageData == null)
                {
                    return new Result<Guid>("下载分割图片失败");
                }

                // 6. 处理图片生成证件照 - 质量优化部分
                _logger.LogInformation("开始处理高质量证件照生成");

                // 转换landmarks为可用的点数组
                var landmarkPoints = ConvertLandmarksToPoints(landmarks);

                // 加载图片到ImageSharp - 使用高质量加载方式
                using var originalImg = Image.Load<Rgba32>(imageData);
                using var segmentedImg = Image.Load<Rgba32>(segmentedImageData);

                // 人脸对齐 - 优化旋转质量
                var (alignedImg, rotatedLandmarks) = AlignFaceHighQuality(segmentedImg, landmarkPoints);

                // 裁剪半身像 - 优化裁剪质量
                var photoSize = GetPhotoSize(size);
                var croppedImg = CropHalfBodyHighQuality(alignedImg, rotatedLandmarks, photoSize);

                // 背景色替换 - 优化边缘处理
                var bgColor = GetBackgroundColor(backgroundColor);
                var finalImg = ReplaceBackgroundHighQuality(croppedImg, bgColor, photoSize);

                // 7. 保存处理后的图片 - 使用高质量JPEG保存
                using var ms = new MemoryStream();
                // 使用高质量保存参数
                await finalImg.SaveAsJpegAsync(ms, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder
                {
                    Quality = 95 // 高质量JPEG
                });

                byte[] processedImageData = ms.ToArray();

                // 8. 上传处理后的图片
                var scope = _context.ServiceProvider.CreateScope();
                var dc = scope.ServiceProvider.GetRequiredService<WTMContext>().DC;
                var wtmFileProvider = scope.ServiceProvider.GetRequiredService<WtmFileProvider>();

                // 获取原图片信息
                var originalFile = await dc.Set<FileAttachment>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(f => f.ID == imageId);

                if (originalFile == null)
                {
                    return new Result<Guid>("原图片不存在");
                }

                // 生成新的文件名
                var sizeText = GetSizeText(size);
                var bgText = GetColorText(backgroundColor);
                var originalFileName = Path.GetFileNameWithoutExtension(originalFile.FileName);
                var extension = Path.GetExtension(originalFile.FileName);
                var newFileName = $"{originalFileName}_{sizeText}{bgText}证件照{extension}";

                _logger.LogInformation(
                    $"准备上传证件照 - 文件名: {newFileName},大小: {processedImageData.Length} bytes");

                // 上传新的证件照文件
                var uploadResult = wtmFileProvider.Upload(
                    fileName: newFileName,
                    fileLength: processedImageData.Length,
                    data: new MemoryStream(processedImageData),
                    group: null, // 文件分组(可选)
                    subdir: null, // 子目录(可选) 
                    extra: null, // 额外信息(可选)
                    saveMode: null, // 存储模式(可选,默认使用配置的模式)
                    dc: dc // 数据上下文
                );

                // 检查上传结果是否为空
                if (uploadResult == null)
                {
                    _logger.LogError("证件照文件上传失败");
                    return new Result<Guid> { 
                        Code = 500,
                        Message = "证件照文件上传失败",
                        Data = Guid.Empty
                    };
                }

                var newFileId = Guid.Parse(uploadResult.GetID());
                await dc.SaveChangesAsync();
                _logger.LogInformation($"高质量证件照文件上传成功，新文件ID: {newFileId}");

                // 删除原图片
                try
                {
                    wtmFileProvider.DeleteFile(imageId.ToString(), dc);
                    await dc.SaveChangesAsync();
                    _logger.LogInformation($"原图片文件已删除，ID: {imageId}");
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"删除原图片失败，但不影响结果：{imageId}");
                }

                return new Result<Guid>
                {
                    Code = 200,
                    Message = "高质量证件照生成成功",
                    Data = newFileId
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"证件照生成异常: {imageId}");
                return new Result<Guid>($"证件照生成异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 高质量人脸对齐算法
        /// </summary>
        private (Image<Rgba32> alignedImg, PointF[] rotatedLandmarks) AlignFaceHighQuality(Image<Rgba32> image,
            PointF[] landmarks)
        {
            // 获取左右眼关键点
            var leftEye = landmarks.Skip(24).Take(15).ToArray();
            var rightEye = landmarks.Skip(39).Take(16).ToArray();

            // 计算眼部中心点
            var leftEyeCenter = new PointF(
                leftEye.Average(p => p.X),
                leftEye.Average(p => p.Y)
            );
            var rightEyeCenter = new PointF(
                rightEye.Average(p => p.X),
                rightEye.Average(p => p.Y)
            );

            // 计算旋转角度
            var dy = rightEyeCenter.Y - leftEyeCenter.Y;
            var dx = rightEyeCenter.X - leftEyeCenter.X;
            var angle = (float)(Math.Atan2(dy, dx) * 180.0 / Math.PI);

            // 计算眼部中心
            var eyeCenter = new PointF(
                (leftEyeCenter.X + rightEyeCenter.X) / 2,
                (leftEyeCenter.Y + rightEyeCenter.Y) / 2
            );

            // 如果角度很小，不进行旋转
            if (Math.Abs(angle) < 0.5f)
            {
                return (image.Clone(), landmarks);
            }

            // 使用高质量的旋转设置
            var rotatedImg = image.Clone();
            rotatedImg.Mutate(x => x.Rotate(angle, KnownResamplers.Bicubic)); // 使用双三次插值提高质量

            // 旋转关键点
            var radians = angle * Math.PI / 180.0;
            var centerX = eyeCenter.X;
            var centerY = eyeCenter.Y;
            var imageHeight = image.Height;

            var rotatedLandmarks = new PointF[landmarks.Length];
            for (int i = 0; i < landmarks.Length; i++)
            {
                var x1 = landmarks[i].X;
                var y1 = imageHeight - landmarks[i].Y;
                var x2 = centerX;
                var y2 = imageHeight - centerY;

                var x = (float)(x2 + Math.Cos(radians) * (x1 - x2) - Math.Sin(radians) * (y1 - y2));
                var y = (float)(y2 + Math.Sin(radians) * (x1 - x2) + Math.Cos(radians) * (y1 - y2));

                rotatedLandmarks[i] = new PointF(x, imageHeight - y);
            }

            return (rotatedImg, rotatedLandmarks);
        }

        /// <summary>
        /// 高质量半身像裁剪算法
        /// </summary>
        private Image<Rgba32> CropHalfBodyHighQuality(Image<Rgba32> image, PointF[] landmarks,
            (int width, int height) size)
        {
            // 根据面部特征计算缩放比例
            var scale = size.height / 4.0f / Math.Abs(landmarks[98].Y - landmarks[56].Y);

            // 高质量缩放图像
            var scaledWidth = (int)(image.Width * scale);
            var scaledHeight = (int)(image.Height * scale);
            var scaledImg = image.Clone();
            scaledImg.Mutate(x => x.Resize(new ResizeOptions
            {
                Size = new Size(scaledWidth, scaledHeight),
                Sampler = KnownResamplers.Bicubic, // 使用双三次插值
                Mode = ResizeMode.Pad,
                PadColor = Color.Transparent
            }));

            // 缩放关键点
            var scaledLandmarks = landmarks.Select(p => new PointF(p.X * scale, p.Y * scale)).ToArray();

            // 计算裁剪中心
            var xCenter = scaledLandmarks[98].X;
            var yCenter = (scaledLandmarks[98].Y + scaledLandmarks[56].Y) / 2;

            // 计算裁剪区域
            var cropLeft = (int)(xCenter - size.width / 2);
            var cropTop = (int)(yCenter - size.height / 2);

            // 边界调整
            var leftAdjust = Math.Max(0, -cropLeft);
            var topAdjust = Math.Max(0, -cropTop);
            cropLeft = Math.Max(0, cropLeft);
            cropTop = Math.Max(0, cropTop);
            var cropRight = Math.Min(scaledImg.Width, cropLeft + size.width);
            var cropBottom = Math.Min(scaledImg.Height, cropTop + size.height);

            // 创建目标尺寸的透明画布
            var result = new Image<Rgba32>(size.width, size.height);

            // 裁剪并放置到画布上
            if (cropRight > cropLeft && cropBottom > cropTop)
            {
                var cropWidth = cropRight - cropLeft;
                var cropHeight = cropBottom - cropTop;

                var croppedImg = scaledImg.Clone();
                croppedImg.Mutate(x => x.Crop(new Rectangle(cropLeft, cropTop, cropWidth, cropHeight)));

                // 在目标画布上放置裁剪后的图像
                result.Mutate(x => x.DrawImage(croppedImg, new Point(leftAdjust, topAdjust), 1.0f));
                croppedImg.Dispose();
            }

            scaledImg.Dispose();
            return result;
        }

        /// <summary>
        /// 高质量背景替换算法，添加边缘平滑处理
        /// </summary>
        private Image<Rgba32> ReplaceBackgroundHighQuality(Image<Rgba32> foregroundImg,
            (byte R, byte G, byte B) backgroundColor, (int width, int height) size)
        {
            // 创建指定颜色的背景
            var result = new Image<Rgba32>(size.width, size.height);
            var bgColor = Color.FromRgb(backgroundColor.R, backgroundColor.G, backgroundColor.B);
            result.Mutate(x => x.BackgroundColor(bgColor));

            // 优化边缘处理
            if (foregroundImg.Width == size.width && foregroundImg.Height == size.height)
            {
                // 边缘平滑处理
                foregroundImg.Mutate(x =>
                {
                    // 细微的高斯模糊可以平滑边缘
                    x.GaussianBlur(0.3f);
                });

                // 使用高质量混合模式
                result.Mutate(ctx => { ctx.DrawImage(foregroundImg, new Point(0, 0), 1.0f); });
            }
            else
            {
                // 需要先调整大小
                var resizedForeground = foregroundImg.Clone();
                resizedForeground.Mutate(x => x.Resize(new ResizeOptions
                {
                    Size = new Size(size.width, size.height),
                    Sampler = KnownResamplers.Bicubic,
                    Mode = ResizeMode.Stretch
                }));

                // 边缘平滑处理
                resizedForeground.Mutate(x => { x.GaussianBlur(0.3f); });

                result.Mutate(ctx => { ctx.DrawImage(resizedForeground, new Point(0, 0), 1.0f); });

                resizedForeground.Dispose();
            }

            return result;
        }

        /// <summary>
        /// 将阿里云返回的landmarks转换为点数组
        /// </summary>
        private PointF[] ConvertLandmarksToPoints(List<float?> landmarks)
        {
            var validLandmarks = landmarks.Where(x => x.HasValue).Select(x => x.Value).ToArray();
            var points = new PointF[validLandmarks.Length / 2];

            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new PointF(validLandmarks[i * 2], validLandmarks[i * 2 + 1]);
            }

            return points;
        }

        /// <summary>
        /// 精确的人脸对齐算法（基于官方Python实现）
        /// </summary>
        private (Image<Rgba32> alignedImg, PointF[] rotatedLandmarks) AlignFaceExact(Image<Rgba32> image,
            PointF[] landmarks)
        {
            // 获取左右眼关键点 (基于105点模型)
            var leftEye = landmarks.Skip(24).Take(15).ToArray(); // 24-38
            var rightEye = landmarks.Skip(39).Take(16).ToArray(); // 39-54

            // 计算眼部中心点
            var leftEyeCenter = new PointF(
                leftEye.Average(p => p.X),
                leftEye.Average(p => p.Y)
            );
            var rightEyeCenter = new PointF(
                rightEye.Average(p => p.X),
                rightEye.Average(p => p.Y)
            );

            // 计算旋转角度
            var dy = rightEyeCenter.Y - leftEyeCenter.Y;
            var dx = rightEyeCenter.X - leftEyeCenter.X;
            var angle = (float)(Math.Atan2(dy, dx) * 180.0 / Math.PI);

            // 计算眼部中心
            var eyeCenter = new PointF(
                (leftEyeCenter.X + rightEyeCenter.X) / 2,
                (leftEyeCenter.Y + rightEyeCenter.Y) / 2
            );

            // 如果角度很小，不进行旋转
            if (Math.Abs(angle) < 1.0f)
            {
                return (image.Clone(), landmarks);
            }

            // 旋转图像
            var rotatedImg = image.Clone();
            rotatedImg.Mutate(x => x.Rotate(angle));

            // 旋转关键点
            var rotatedLandmarks = new PointF[landmarks.Length];
            var radians = angle * Math.PI / 180.0;
            var centerX = eyeCenter.X;
            var centerY = eyeCenter.Y;
            var imageHeight = image.Height;

            for (int i = 0; i < landmarks.Length; i++)
            {
                var x1 = landmarks[i].X;
                var y1 = imageHeight - landmarks[i].Y; // 转换为数学坐标系
                var x2 = centerX;
                var y2 = imageHeight - centerY;

                // 使用与Python一致的旋转公式
                var x = (float)(x2 + Math.Cos(radians) * (x1 - x2) - Math.Sin(radians) * (y1 - y2));
                var y = (float)(y2 + Math.Sin(radians) * (x1 - x2) + Math.Cos(radians) * (y1 - y2));

                rotatedLandmarks[i] = new PointF(x, imageHeight - y); // 转换回图像坐标系
            }

            return (rotatedImg, rotatedLandmarks);
        }

        /// <summary>
        /// 精确的半身像裁剪算法（基于官方Python实现）
        /// </summary>
        private Image<Rgba32> CropHalfBodyExact(Image<Rgba32> image, PointF[] landmarks, (int width, int height) size)
        {
            // 根据官方Python算法计算缩放比例
            var scale = size.height / 4.0f / Math.Abs(landmarks[98].Y - landmarks[56].Y);

            // 缩放图像
            var scaledWidth = (int)(image.Width * scale);
            var scaledHeight = (int)(image.Height * scale);
            var scaledImg = image.Clone();
            scaledImg.Mutate(x => x.Resize(scaledWidth, scaledHeight));

            // 缩放关键点
            var scaledLandmarks = landmarks.Select(p => new PointF(p.X * scale, p.Y * scale)).ToArray();

            // 计算裁剪中心和区域
            var xCenter = scaledLandmarks[98].X; // 下巴点X坐标
            var yCenter = (scaledLandmarks[98].Y + scaledLandmarks[56].Y) / 2; // 下巴和额头中点

            var cropLeft = (int)(xCenter - size.width / 2);
            var cropTop = (int)(yCenter - size.height / 2);
            var cropRight = cropLeft + size.width;
            var cropBottom = cropTop + size.height;

            // 边界调整
            var leftAdjust = Math.Max(0, -cropLeft);
            var topAdjust = Math.Max(0, -cropTop);
            cropLeft = Math.Max(0, cropLeft);
            cropTop = Math.Max(0, cropTop);
            cropRight = Math.Min(scaledImg.Width, cropRight);
            cropBottom = Math.Min(scaledImg.Height, cropBottom);

            // 创建目标尺寸的透明画布
            var result = new Image<Rgba32>(size.width, size.height);

            // 裁剪并放置到画布上
            if (cropRight > cropLeft && cropBottom > cropTop)
            {
                var cropWidth = cropRight - cropLeft;
                var cropHeight = cropBottom - cropTop;

                var croppedImg = scaledImg.Clone();
                croppedImg.Mutate(x => x.Crop(new Rectangle(cropLeft, cropTop, cropWidth, cropHeight)));

                // 在目标画布上放置裁剪后的图像
                result.Mutate(x => x.DrawImage(croppedImg, new Point(leftAdjust, topAdjust), 1.0f));
                croppedImg.Dispose();
            }

            scaledImg.Dispose();
            return result;
        }

        /// <summary>
        /// 精确的背景替换算法（基于官方Python实现）
        /// </summary>
        private Image<Rgba32> ReplaceBackgroundExact(Image<Rgba32> foregroundImg,
            (byte R, byte G, byte B) backgroundColor, (int width, int height) size)
        {
            // 创建指定颜色的背景
            var result = new Image<Rgba32>(size.width, size.height);
            var bgColor = Color.FromRgb(backgroundColor.R, backgroundColor.G, backgroundColor.B);
            result.Mutate(x => x.BackgroundColor(bgColor));

            // 根据Alpha通道混合前景和背景
            result.Mutate(ctx => { ctx.DrawImage(foregroundImg, new Point(0, 0), 1.0f); });

            return result;
        }

        /// <summary>
        /// 下载网络图片（用于获取分割结果）
        /// </summary>
        private async Task<byte[]> DownloadImageAsync(string imageUrl)
        {
            try
            {
                using var httpClient = new HttpClient();
                return await httpClient.GetByteArrayAsync(imageUrl);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"下载图片失败: {imageUrl}");
                return null;
            }
        }

        /// <summary>
        /// 获取尺寸文本描述
        /// </summary>
        private string GetSizeText(IdPhotoSize size) => size switch
        {
            IdPhotoSize.OneInch => "一寸",
            IdPhotoSize.TwoInch => "二寸",
            IdPhotoSize.SmallTwoInch => "小二寸",
            _ => "一寸"
        };

        /// <summary>
        /// 获取颜色文本描述
        /// </summary>
        private string GetColorText(IdPhotoBackgroundColor color) => color switch
        {
            IdPhotoBackgroundColor.White => "白底",
            IdPhotoBackgroundColor.Red => "红底",
            IdPhotoBackgroundColor.Blue => "蓝底",
            _ => "白底"
        };

        /// <summary>
        /// 获取证件照尺寸
        /// </summary>
        private (int width, int height) GetPhotoSize(IdPhotoSize size)
        {
            return size switch
            {
                IdPhotoSize.OneInch => (295, 413),
                IdPhotoSize.TwoInch => (413, 579),
                IdPhotoSize.SmallTwoInch => (413, 531),
                _ => (295, 413)
            };
        }

        /// <summary>
        /// 获取背景颜色RGB值
        /// </summary>
        private (byte R, byte G, byte B) GetBackgroundColor(IdPhotoBackgroundColor backgroundColor)
        {
            return backgroundColor switch
            {
                IdPhotoBackgroundColor.White => (255, 255, 255),
                IdPhotoBackgroundColor.Red => (255, 0, 0),
                IdPhotoBackgroundColor.Blue => (0, 0, 255),
                _ => (255, 255, 255)
            };
        }

        /// <summary>
        /// 处理生成证件照（人脸对齐、裁剪、背景替换）
        /// 基于官方算法优化实现
        /// </summary>
        private async Task<byte[]> ProcessIdPhotoAsync(byte[] originalImage, byte[] segmentedImage,
            List<float?> landmarks, (int width, int height) size, (byte R, byte G, byte B) backgroundColor)
        {
            try
            {
                _logger.LogInformation("开始处理证件照：人脸对齐、裁剪、背景替换");

                // 转换List<float?>为float[]，过滤掉null值
                var validLandmarks = landmarks.Where(x => x.HasValue).Select(x => x.Value).ToArray();

                if (validLandmarks.Length < 210) // 105个点，每个点x,y坐标，共210个值
                {
                    _logger.LogError($"关键点数量不足: {validLandmarks.Length}，期望210个");
                    return null;
                }

                // 将landmarks转换为105个点的数组
                var landmarkPoints = new PointF[105];
                for (int i = 0; i < 105; i++)
                {
                    landmarkPoints[i] = new PointF(validLandmarks[i * 2], validLandmarks[i * 2 + 1]);
                }

                // 使用SixLabors.ImageSharp处理图像
                using var originalImg = Image.Load<Rgba32>(originalImage);
                using var segmentedImg = Image.Load<Rgba32>(segmentedImage);

                // 1. 人脸对齐处理（按照官方算法）
                var (alignedImg, rotatedLandmarks) = AlignFaceOptimized(segmentedImg, landmarkPoints);

                // 2. 裁剪半身像（按照官方算法）
                var croppedImg = CropHalfBodyOptimized(alignedImg, rotatedLandmarks, size);

                // 3. 背景颜色替换（按照官方算法）
                var finalImg = ReplaceBackgroundOptimized(croppedImg, backgroundColor, size);

                // 转换为字节数组
                using var ms = new MemoryStream();
                await finalImg.SaveAsJpegAsync(ms);

                alignedImg?.Dispose();
                croppedImg?.Dispose();
                finalImg?.Dispose();

                return ms.ToArray();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理证件照失败");
                return null;
            }
        }

        /// <summary>
        /// 优化的人脸对齐算法（严格按照官方实现）
        /// </summary>
        private (Image<Rgba32> alignedImg, PointF[] rotatedLandmarks) AlignFaceOptimized(
            Image<Rgba32> image, PointF[] landmarks)
        {
            // 官方算法：获取左右眼关键点 (基于105点模型)
            // 左眼: landmarks[24:39] (索引24-38)
            // 右眼: landmarks[40:55] (索引39-54)
            var leftEye = landmarks.Skip(24).Take(15).ToArray(); // 24-38
            var rightEye = landmarks.Skip(39).Take(16).ToArray(); // 39-54

            // 计算眼部中心点（严格按照官方算法）
            var leftEyeCenter = new PointF(
                leftEye.Average(p => p.X),
                leftEye.Average(p => p.Y)
            );
            var rightEyeCenter = new PointF(
                rightEye.Average(p => p.X),
                rightEye.Average(p => p.Y)
            );

            _logger.LogInformation(
                $"左眼中心: ({leftEyeCenter.X}, {leftEyeCenter.Y}), 右眼中心: ({rightEyeCenter.X}, {rightEyeCenter.Y})");

            // 计算旋转角度（官方公式）
            var dy = rightEyeCenter.Y - leftEyeCenter.Y;
            var dx = rightEyeCenter.X - leftEyeCenter.X;
            var angle = (float)(Math.Atan2(dy, dx) * 180.0 / Math.PI);

            _logger.LogInformation($"计算的旋转角度: {angle} 度");

            // 计算眼部中心（官方算法）
            var eyeCenter = new PointF(
                (leftEyeCenter.X + rightEyeCenter.X) / 2,
                (leftEyeCenter.Y + rightEyeCenter.Y) / 2
            );

            _logger.LogInformation($"旋转中心点: ({eyeCenter.X}, {eyeCenter.Y})");

            // 如果角度很小，不进行旋转（避免不必要的处理）
            if (Math.Abs(angle) < 1.0f)
            {
                _logger.LogInformation("角度很小，跳过旋转");
                return (image.Clone<Rgba32>(), landmarks);
            }

            // 创建旋转后的图像
            var rotatedImg = image.Clone<Rgba32>();

            // 使用正确的 Rotate 方法语法
            rotatedImg.Mutate(x => x.Rotate(angle));

            // 旋转关键点（严格按照官方算法）
            var rotatedLandmarks = RotateLandmarksOptimized(landmarks, eyeCenter, angle, image.Height);

            return (rotatedImg, rotatedLandmarks);
        }

        /// <summary>
        /// 优化的关键点旋转算法（严格按照官方实现）
        /// </summary>
        private PointF[] RotateLandmarksOptimized(PointF[] landmarks, PointF center, float angle, int imageHeight)
        {
            // 官方算法的旋转公式
            var radians = angle * Math.PI / 180.0;
            var rotated = new PointF[landmarks.Length];

            for (int i = 0; i < landmarks.Length; i++)
            {
                var point = landmarks[i];

                // 官方算法：先转换坐标系（图像坐标系转数学坐标系）
                var x1 = point.X;
                var y1 = imageHeight - point.Y;
                var x2 = center.X;
                var y2 = imageHeight - center.Y;

                // 官方旋转公式
                var x = (float)(x2 + Math.Cos(radians) * (x1 - x2) - Math.Sin(radians) * (y1 - y2));
                var y = (float)(y2 + Math.Sin(radians) * (x1 - x2) + Math.Cos(radians) * (y1 - y2));

                // 转换回图像坐标系
                rotated[i] = new PointF(x, imageHeight - y);
            }

            return rotated;
        }

        /// <summary>
        /// 优化的半身像裁剪算法（基于官方实现）
        /// </summary>
        private Image<Rgba32> CropHalfBodyOptimized(Image<Rgba32> image, PointF[] landmarks,
            (int width, int height) targetSize)
        {
            // 根据下巴和额头点计算缩放比例（官方算法）
            var chinPoint = landmarks[98]; // 下巴点
            var foreheadPoint = landmarks[56]; // 额头点

            var faceHeight = Math.Abs(chinPoint.Y - foreheadPoint.Y);
            var scale = targetSize.height / 4.0f /
                        faceHeight; // 官方公式：size[1] / 4 / abs(landmarks[98][1] - landmarks[56][1])

            // 缩放图像
            var scaledWidth = (int)(image.Width * scale);
            var scaledHeight = (int)(image.Height * scale);
            var scaledImg = image.Clone<Rgba32>();
            scaledImg.Mutate(x => x.Resize(scaledWidth, scaledHeight));

            // 缩放关键点
            var scaledLandmarks = landmarks.Select(p => new PointF(p.X * scale, p.Y * scale)).ToArray();

            // 计算裁剪中心（官方算法）
            var xCenter = scaledLandmarks[98].X; // 以下巴点X坐标为中心
            var yCenter = (scaledLandmarks[98].Y + scaledLandmarks[56].Y) / 2; // 下巴和额头中点

            // 计算裁剪区域
            var cropLeft = (int)(xCenter - targetSize.width / 2.0f);
            var cropRight = (int)(xCenter + targetSize.width / 2.0f);
            var cropTop = (int)(yCenter - targetSize.height / 2.0f);
            var cropBottom = (int)(yCenter + targetSize.height / 2.0f);

            // 边界检查
            cropLeft = Math.Max(0, cropLeft);
            cropTop = Math.Max(0, cropTop);
            cropRight = Math.Min(scaledImg.Width, cropRight);
            cropBottom = Math.Min(scaledImg.Height, cropBottom);

            var cropWidth = cropRight - cropLeft;
            var cropHeight = cropBottom - cropTop;

            // 创建目标尺寸的画布
            var result = new Image<Rgba32>(targetSize.width, targetSize.height, Color.Transparent);

            // 裁剪并居中放置
            if (cropWidth > 0 && cropHeight > 0)
            {
                var croppedImg = scaledImg.Clone<Rgba32>();
                croppedImg.Mutate(x => x.Crop(new Rectangle(cropLeft, cropTop, cropWidth, cropHeight)));

                // 计算在目标画布上的位置（居中）
                var pasteLeft = Math.Max(0, -Math.Min(0, (int)(xCenter - targetSize.width / 2.0f)));
                var pasteTop = Math.Max(0, targetSize.height - cropHeight);

                result.Mutate(x => x.DrawImage(croppedImg, new Point(pasteLeft, pasteTop), 1.0f));
                croppedImg.Dispose();
            }

            scaledImg.Dispose();
            return result;
        }

        /// <summary>
        /// 优化的背景替换算法（基于官方实现）
        /// </summary>
        private Image<Rgba32> ReplaceBackgroundOptimized(Image<Rgba32> foregroundImg,
            (byte R, byte G, byte B) backgroundColor, (int width, int height) size)
        {
            // 创建目标尺寸的背景图像
            var result = new Image<Rgba32>(size.width, size.height);
            var bgColor = Color.FromRgb(backgroundColor.R, backgroundColor.G, backgroundColor.B);

            // 填充背景色
            result.Mutate(x => x.BackgroundColor(bgColor));

            // 确保前景图像尺寸匹配
            if (foregroundImg.Width != size.width || foregroundImg.Height != size.height)
            {
                var resizedForeground = foregroundImg.Clone<Rgba32>();
                resizedForeground.Mutate(x => x.Resize(size.width, size.height));

                // 使用alpha通道进行混合
                result.Mutate(x => x.DrawImage(resizedForeground, new Point(0, 0), 1.0f));

                resizedForeground.Dispose();
            }
            else
            {
                // 直接绘制
                result.Mutate(x => x.DrawImage(foregroundImg, new Point(0, 0), 1.0f));
            }

            return result;
        }

        /// <summary>
        /// 人脸对齐：根据眼部关键点旋转图像
        /// </summary>
        private (Image<Rgba32> alignedImg, PointF eyeCenter, float angle, PointF[] rotatedLandmarks) AlignFace(
            Image<Rgba32> image, float[] landmarks)
        {
            var landmarkPoints = new PointF[landmarks.Length / 2];
            for (int i = 0; i < landmarkPoints.Length; i++)
            {
                landmarkPoints[i] = new PointF(landmarks[i * 2], landmarks[i * 2 + 1]);
            }

            // 获取左右眼关键点 (基于105点模型)
            var leftEye = landmarkPoints.Skip(24).Take(15).ToArray();
            var rightEye = landmarkPoints.Skip(39).Take(16).ToArray();

            // 计算眼部中心点
            var leftEyeCenter = new PointF(
                leftEye.Average(p => p.X),
                leftEye.Average(p => p.Y)
            );
            var rightEyeCenter = new PointF(
                rightEye.Average(p => p.X),
                rightEye.Average(p => p.Y)
            );

            // 计算旋转角度
            var dy = rightEyeCenter.Y - leftEyeCenter.Y;
            var dx = rightEyeCenter.X - leftEyeCenter.X;
            var angle = (float)(Math.Atan2(dy, dx) * 180.0 / Math.PI);

            // 计算眼部中心
            var eyeCenter = new PointF(
                (leftEyeCenter.X + rightEyeCenter.X) / 2,
                (leftEyeCenter.Y + rightEyeCenter.Y) / 2
            );

            // 创建旋转后的图像
            var rotatedImg = image.Clone<Rgba32>();
            rotatedImg.Mutate(x => x.Rotate(angle));

            // 旋转关键点
            var rotatedLandmarks = RotateLandmarks(landmarkPoints, eyeCenter, angle, image.Height);

            return (rotatedImg, eyeCenter, angle, rotatedLandmarks);
        }

        /// <summary>
        /// 旋转关键点坐标
        /// </summary>
        private PointF[] RotateLandmarks(PointF[] landmarks, PointF center, float angle, int imageHeight)
        {
            var radians = angle * Math.PI / 180.0;
            var rotated = new PointF[landmarks.Length];

            for (int i = 0; i < landmarks.Length; i++)
            {
                var point = landmarks[i];
                var x1 = point.X;
                var y1 = imageHeight - point.Y; // 转换坐标系
                var x2 = center.X;
                var y2 = imageHeight - center.Y;

                var x = (float)(x2 + Math.Cos(radians) * (x1 - x2) - Math.Sin(radians) * (y1 - y2));
                var y = (float)(y2 + Math.Sin(radians) * (x1 - x2) + Math.Cos(radians) * (y1 - y2));

                rotated[i] = new PointF(x, imageHeight - y); // 转换回原坐标系
            }

            return rotated;
        }

        /// <summary>
        /// 裁剪半身像
        /// </summary>
        private Image<Rgba32> CropHalfBody(Image<Rgba32> image, PointF[] landmarks, (int width, int height) targetSize)
        {
            // 根据面部关键点确定裁剪区域
            var chinPoint = landmarks[98];
            var foreheadPoint = landmarks[56];

            // 计算缩放比例
            var faceHeight = Math.Abs(chinPoint.Y - foreheadPoint.Y);
            var scale = targetSize.height / 4.0f / faceHeight;

            // 缩放图像
            var scaledWidth = (int)(image.Width * scale);
            var scaledHeight = (int)(image.Height * scale);
            var scaledImg = image.Clone<Rgba32>();
            scaledImg.Mutate(x => x.Resize(scaledWidth, scaledHeight));

            // 缩放关键点
            var scaledLandmarks = landmarks.Select(p => new PointF(p.X * scale, p.Y * scale)).ToArray();

            // 计算裁剪中心
            var centerX = scaledLandmarks[98].X;
            var centerY = (scaledLandmarks[98].Y + scaledLandmarks[56].Y) / 2;

            // 计算裁剪区域
            var cropLeft = Math.Max(0, (int)(centerX - targetSize.width / 2.0f));
            var cropTop = Math.Max(0, (int)(centerY - targetSize.height / 2.0f));
            var cropRight = Math.Min(scaledImg.Width, cropLeft + targetSize.width);
            var cropBottom = Math.Min(scaledImg.Height, cropTop + targetSize.height);

            // 裁剪图像
            var cropWidth = cropRight - cropLeft;
            var cropHeight = cropBottom - cropTop;

            var croppedImg = scaledImg.Clone<Rgba32>();
            croppedImg.Mutate(x => x.Crop(new Rectangle(cropLeft, cropTop, cropWidth, cropHeight)));

            scaledImg.Dispose();
            return croppedImg;
        }

        /// <summary>
        /// 背景颜色替换
        /// </summary>
        private Image<Rgba32> ReplaceBackground(Image<Rgba32> foregroundImg, Image<Rgba32> maskImg,
            (byte R, byte G, byte B) backgroundColor, (int width, int height) size)
        {
            // 创建目标尺寸的背景图像
            var result = new Image<Rgba32>(size.width, size.height);
            var bgColor = Color.FromRgb(backgroundColor.R, backgroundColor.G, backgroundColor.B);

            result.Mutate(x => x.BackgroundColor(bgColor));

            // 调整前景图像尺寸并居中放置
            var resizedForeground = foregroundImg.Clone<Rgba32>();
            resizedForeground.Mutate(x => x.Resize(size.width, size.height));

            // 将前景图像绘制到背景上
            result.Mutate(x => x.DrawImage(resizedForeground, new Point(0, 0), 1.0f));

            resizedForeground.Dispose();
            return result;
        }


        /// <summary>
        /// 根据图片ID获取图片数据
        /// 支持数据库存储和本地文件存储两种模式
        /// </summary>
        /// <param name="imageId">图片ID</param>
        /// <returns>图片字节数组</returns>
        private async Task<Result<byte[]>> GetImageDataAsync(Guid imageId)
        {
            try
            {
                var scope = _context.ServiceProvider.CreateScope();
                var dc = scope.ServiceProvider.GetRequiredService<WTMContext>().DC;

                // 根据图片ID获取图片文件
                var fileAttachment = await dc.Set<FileAttachment>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(f => f.ID == imageId);

                if (fileAttachment == null)
                {
                    _logger.LogWarning($"未找到图片，ImageId: {imageId}");
                    return new Result<byte[]>("图片不存在");
                }

                byte[] imageData = null;
                _logger.LogInformation($"图片存储模式: {fileAttachment.SaveMode}");

                // 根据存储类型获取图片数据
                if (string.Equals(fileAttachment.SaveMode, "database", StringComparison.OrdinalIgnoreCase))
                {
                    // 数据库存储模式
                    if (fileAttachment.FileData == null || fileAttachment.FileData.Length == 0)
                    {
                        _logger.LogWarning($"数据库存储的图片内容为空，ImageId: {imageId}");
                        return new Result<byte[]>("数据库存储的图片内容为空");
                    }

                    imageData = fileAttachment.FileData;
                    _logger.LogInformation($"从数据库获取图片数据成功，大小: {imageData.Length} bytes");
                }
                else if (string.Equals(fileAttachment.SaveMode, "local", StringComparison.OrdinalIgnoreCase))
                {
                    // 本地文件存储模式
                    if (string.IsNullOrEmpty(fileAttachment.Path))
                    {
                        _logger.LogWarning($"本地存储的图片路径为空，ImageId: {imageId}");
                        return new Result<byte[]>("本地存储的图片路径为空");
                    }

                    var fullPath = Path.IsPathRooted(fileAttachment.Path)
                        ? fileAttachment.Path
                        : Path.Combine(Directory.GetCurrentDirectory(), fileAttachment.Path);

                    if (!File.Exists(fullPath))
                    {
                        _logger.LogWarning($"本地图片文件不存在，路径: {fullPath}");
                        return new Result<byte[]>($"本地图片文件不存在: {fileAttachment.Path}");
                    }

                    try
                    {
                        imageData = await File.ReadAllBytesAsync(fullPath);
                        _logger.LogInformation($"从本地文件获取图片数据成功，路径: {fullPath}, 大小: {imageData.Length} bytes");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"读取本地图片文件失败，路径: {fullPath}");
                        return new Result<byte[]>($"读取本地图片文件失败: {ex.Message}");
                    }
                }
                else
                {
                    _logger.LogWarning($"不支持的存储模式: {fileAttachment.SaveMode}，ImageId: {imageId}");
                    return new Result<byte[]>($"不支持的存储模式: {fileAttachment.SaveMode}");
                }

                if (imageData == null || imageData.Length == 0)
                {
                    _logger.LogWarning($"获取到的图片数据为空，ImageId: {imageId}");
                    return new Result<byte[]>("图片数据为空");
                }

                return new Result<byte[]>
                {
                    Code = 200,
                    Message = "获取图片数据成功",
                    Data = imageData
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取图片数据异常，ImageId: {imageId}");
                return new Result<byte[]>($"获取图片数据异常：{ex.Message}");
            }
        }
    }
}